package it.sephiroth.android.library.imagezoom;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import com.gq.dragonball.R;
import com.gq.utils.CustomViewPager;
import com.gq.utils.ImageDownloader;
import com.gq.utils.ImageViewPager;
import com.rtst.widget.tab.SwipeyTabs;

public class ImageViewTouch extends ImageViewTouchBase {
	protected ScaleGestureDetector mScaleDetector;
	protected GestureDetector mGestureDetector;
	protected GestureListener mGestureListener;
	protected ScaleListener	mScaleListener;
	protected int mTouchSlop;
	protected float	mCurrentScaleFactor;
	protected float	mScaleFactor;
	protected int mDoubleTapDirection;
	private boolean multitouch;
	private boolean hidebutton;
	private ImageDownloader imageDownloader;
	private int timeout;
	private Bitmap bitmap;
	private int position;
	private String source;
	private ImageViewPager imageViewPager;
	static final float MIN_ZOOM = 0.9f;
	private static final int COMPLETE = 0;
	private static final int FAILED = 1;
	private Animation fadeIn;
	private Animation fadeOut;
	private Bitmap noNetwork;
	private String TAG = ImageViewTouch.class.getSimpleName();
	private CustomViewPager viewPager;
	private SwipeyTabs mTabs;
	
	public void initData()
	{
		setImageDownloader(new ImageDownloader());
		setUpButton();
		setFadeIn(AnimationUtils.loadAnimation(getContext(), R.anim.fade_in));
		setFadeOut(AnimationUtils.loadAnimation(getContext(), R.anim.fade_out));
		noNetwork = BitmapFactory.decodeResource(getResources(), R.drawable.nonetwork);
	}
	
	public String getUrl(String source) {
		if (source.startsWith("http://")) return source;
		return String.format("%s%s", "http://api.vietcntt.net/", source);
	}
	
	public void prepareDownload(String url) {
		final String lurl = getUrl(url);
		setSource(url);
		startAnimation(getFadeOut());
		setVisibility(View.GONE);
		getImageViewPager().getProgressBar().setVisibility(View.VISIBLE);
//		getImageDownloader().download(lurl, ImageViewTouch.this);
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					setBitmap(getImageDownloader().downloadBitmap(lurl));
					imageLoadedHandler.sendEmptyMessage(COMPLETE);
				} catch (Exception e) {
					imageLoadedHandler.sendEmptyMessage(FAILED);
				}
			}
		}).start();
	}
	
	private final Handler imageLoadedHandler = new Handler(new Callback() {
		@Override
		public boolean handleMessage(Message msg) {
			switch (msg.what) {
				case COMPLETE:
					setVisibility(View.VISIBLE);
					setImageBitmapReset(getBitmap(), 0, true);
					startAnimation(getFadeIn());
					getImageViewPager().getProgressBar().setVisibility(View.GONE);
					break;
				case FAILED:
					setVisibility(View.VISIBLE);
					setImageBitmapReset(noNetwork, 0, true);
					startAnimation(getFadeIn());
					getImageViewPager().getProgressBar().setVisibility(View.GONE);
					break;
				default:
					break;
			}
			return true;
		}		
	});
	
	public void setUpButton() {
		setMultitouch(false); setHidebutton(false); 
		getImageViewPager().getButtonZoomOut().setEnabled(false);
		setTimeout(3000);
		getImageViewPager().getButtonZoomIn().setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				disablePaging();
				zoomTo(getScale() * 2f, 50);
				getImageViewPager().getButtonZoomOut().setEnabled(true);
			}
		});
		getImageViewPager().getButtonZoomOut().setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				float _scale = getScale();
				if (_scale > 2f) {
					zoomTo(_scale * 0.5f, 50);
					getImageViewPager().getButtonZoomOut().setEnabled(true);
				} else if (_scale > 1f){
					enablePaging();
					zoomTo(1f, 50);
					getImageViewPager().getButtonZoomOut().setEnabled(false);
				}				
			}
		}); 
	}
	
	
	public ImageViewTouch( Context context, AttributeSet attrs )
	{
		super( context, attrs );
	}
	
	@Override
	protected void init()
	{
		super.init();
		mTouchSlop = ViewConfiguration.getTouchSlop();
		mGestureListener = new GestureListener();
		mScaleListener = new ScaleListener();
		mScaleDetector = new ScaleGestureDetector( getContext(), mScaleListener );
		mGestureDetector = new GestureDetector( getContext(), mGestureListener, null, true );
		mCurrentScaleFactor = 1f;
		mDoubleTapDirection = 1;
	}
	
	@Override
	public void setImageRotateBitmapReset( RotateBitmap bitmap, boolean reset )
	{
		super.setImageRotateBitmapReset( bitmap, reset );
		mScaleFactor = getMaxZoom() / 3;
	}
	
	@Override
	public boolean onTouchEvent( MotionEvent event )
	{
		mScaleDetector.onTouchEvent( event );
		if ( !mScaleDetector.isInProgress() ) mGestureDetector.onTouchEvent( event );
		int action = event.getAction();
		switch ( action & MotionEvent.ACTION_MASK ) {
			case MotionEvent.ACTION_UP:
				if ( getScale() < 1f ) {
					enablePaging();
					zoomTo( 1f, 50 );
				}
				break;
		}
		return true;
	}
	
	@Override
	protected void onZoom( float scale )
	{
		super.onZoom( scale );
		if ( !mScaleDetector.isInProgress() ) mCurrentScaleFactor = scale;
	}
	
	protected float onDoubleTapPost( float scale, float maxZoom )
	{
		if ( mDoubleTapDirection == 1 ) {
			if ( ( scale + ( mScaleFactor * 2 ) ) <= maxZoom ) {
				return scale + mScaleFactor;
			} else {
				mDoubleTapDirection = -1;
				return maxZoom;
			}
		} else {
			mDoubleTapDirection = 1;
			return 1f;
		}
	}
	
	class GestureListener extends GestureDetector.SimpleOnGestureListener {
		
		@Override
		public boolean onDoubleTap( MotionEvent e )
		{
			if (getScale() > 1f) {
				enablePaging();
				zoomTo(1f, e.getX(), e.getY(), 200 );
				getImageViewPager().getButtonZoomOut().setEnabled(false);
			} else {
				disablePaging();
				zoomTo(getScale() * 2f, e.getX(), e.getY(), 200 );
				getImageViewPager().getButtonZoomOut().setEnabled(true);
			}
			invalidate();
			return super.onDoubleTap(e);
		}
		
		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			if (getScale() == 1f && isHidebutton()) {
				showZoomButton();
			}
			return super.onSingleTapUp(e);
		}
		
		@Override
		public boolean onScroll( MotionEvent e1, MotionEvent e2, float distanceX, float distanceY )
		{
			if ( e1 == null || e2 == null ) return false;
			if ( e1.getPointerCount() > 1 || e2.getPointerCount() > 1 ) return false;
			if ( mScaleDetector.isInProgress() ) return false;
			if ( getScale() == 1f ) {
				enablePaging();
				return false;
			}
			scrollBy( -distanceX, -distanceY );
			invalidate();
			return super.onScroll( e1, e2, distanceX, distanceY );
		}
		
		@Override
		public boolean onFling( MotionEvent e1, MotionEvent e2, float velocityX, float velocityY )
		{
			//System.out.println("---- onFling is called !!!");
			if ( e1.getPointerCount() > 1 || e2.getPointerCount() > 1 ) return false;
			if ( mScaleDetector.isInProgress() ) return false;
			float diffX = e2.getX() - e1.getX();
			float diffY = e2.getY() - e1.getY();
			if ( Math.abs( velocityX ) > 800 || Math.abs( velocityY ) > 800 ) {
				scrollBy( diffX / 2, diffY / 2, 300 );
				invalidate();
			}
			return super.onFling( e1, e2, velocityX, velocityY );
		}
	}
	
	class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
		
		@SuppressWarnings( "unused" )
		@Override
		public boolean onScale( ScaleGestureDetector detector )
		{
			float span = detector.getCurrentSpan() - detector.getPreviousSpan();
			float targetScale = mCurrentScaleFactor * detector.getScaleFactor();
			if ( true ) {
				setMultitouch(true);
				hideZoomButton();
				targetScale = Math.min( getMaxZoom(), Math.max( targetScale, MIN_ZOOM ) );
				if (targetScale > 1f) {
					disablePaging();
				} else {
					enablePaging();
				}
				zoomTo( targetScale, detector.getFocusX(), detector.getFocusY() );
				mCurrentScaleFactor = Math.min( getMaxZoom(), Math.max( targetScale, MIN_ZOOM ) );
				mDoubleTapDirection = 1;
				invalidate();
				return true;
			}
			return false;
		}
	}
	
	public void hideZoomButton() {
		getImageViewPager().getButtonZoomIn().setVisibility(View.GONE);
		getImageViewPager().getButtonZoomOut().setVisibility(View.GONE);
	}
	
	public void showZoomButton() {
		getImageViewPager().getButtonZoomIn().setVisibility(View.VISIBLE);
		getImageViewPager().getButtonZoomOut().setVisibility(View.VISIBLE);
	}
	
	public ImageViewPager getImageViewPager() {
		return imageViewPager;
	}

	public void setImageViewPager(ImageViewPager imageViewPager) {
		this.imageViewPager = imageViewPager;
	}

	public boolean isMultitouch() {
		return multitouch;
	}

	public void setMultitouch(boolean multitouch) {
		this.multitouch = multitouch;
	}

	public int getTimeout() {
		return timeout;
	}

	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}

	public Bitmap getBitmap() {
		return bitmap;
	}

	public void setBitmap(Bitmap bitmap) {
		this.bitmap = bitmap;
	}

	public ImageDownloader getImageDownloader() {
		return imageDownloader;
	}

	public void setImageDownloader(ImageDownloader imageDownloader) {
		this.imageDownloader = imageDownloader;
	}
	
	public int getPosition() {
		return position;
	}

	public void setPosition(int position) {
		this.position = position;
	}
	
	public String getSource() {
		return source;
	}

	public void setSource(String source) {
		this.source = source;
	}

	public boolean isHidebutton() {
		return hidebutton;
	}

	public void setHidebutton(boolean hidebutton) {
		this.hidebutton = hidebutton;
	}

	public Animation getFadeIn() {
		return fadeIn;
	}

	public void setFadeIn(Animation fadeIn) {
		this.fadeIn = fadeIn;
	}

	public Animation getFadeOut() {
		return fadeOut;
	}

	public void setFadeOut(Animation fadeOut) {
		this.fadeOut = fadeOut;
	}

	public CustomViewPager getViewPager() {
		return viewPager;
	}

	public void setViewPager(CustomViewPager viewPager) {
		this.viewPager = viewPager;
	}
	
	private void disablePaging() {
		//System.out.println("######################## PAGING DISABLE !!!");
		getViewPager().setPagingEnabled(false);
		getmTabs().setVisibility(View.GONE);
	}
	
	private void enablePaging() {
		//System.out.println("######################## PAGING ENABLE !!!");
		getViewPager().setPagingEnabled(true);
		getmTabs().setVisibility(View.VISIBLE);
	}

	public SwipeyTabs getmTabs() {
		return mTabs;
	}

	public void setmTabs(SwipeyTabs mTabs) {
		this.mTabs = mTabs;
	}
}
